home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / gnu / gnumake / pdmake.zoo / make.c < prev    next >
C/C++ Source or Header  |  1991-09-25  |  11KB  |  525 lines

  1.     /***************************************************************\
  2.     *                                *
  3.     *  PDMAKE, Atari ST version                    *
  4.     *                                *
  5.     *  Adapted from mod.sources Vol 7 Issue 71, 1986-12-03.        *
  6.     *                                *
  7.     *  This port makes extensive use of the original net.sources    *
  8.     *  port by Jwahar Bammi.                    *
  9.     *                                *
  10.     *      Ton van Overbeek                        *
  11.     *      Email: TPC862@ESTEC.BITNET                *
  12.     *             TPC862%ESTEC.BITNET@WISCVM.WISC.EDU    (ARPA)    *
  13.     *             ...!mcvax!tpc862%estec.bitnet   (UUCP Europe)    *
  14.     *             ...!ucbvax!tpc862%estec.bitnet  (UUCP U.S.A.)    *
  15.     *             71450,3537  (CompuServe)                *
  16.     *                                *
  17.     \***************************************************************/
  18.  
  19. /*
  20.  *    Do the actual making for make
  21.  */
  22.  
  23. #include <stdio.h>
  24.  
  25. #ifdef unix
  26. #include <sys/types.h>
  27. #include <sys/stat.h>
  28. #include <sys/errno.h>
  29. #endif
  30. #ifdef eon
  31. #include <sys/stat.h>
  32. #include <sys/err.h>
  33. #endif
  34. #ifdef os9
  35. #include <time.h>
  36. #include <os9.h>
  37. #include <modes.h>
  38. #include <direct.h>
  39. #include <errno.h>
  40. #endif
  41.  
  42. #include "h.h"
  43. #ifdef ATARIST
  44. #include "astat.h"
  45. #define time Time
  46. #endif
  47.  
  48. /*
  49.  *    Exec a shell that returns exit status correctly (/bin/esh).
  50.  *    The standard EON shell returns the process number of the last
  51.  *    async command, used by the debugger (ugg).
  52.  *    [exec on eon is like a fork+exec on unix]
  53.  */
  54. int
  55. dosh(string, shell)
  56. char *    string;
  57. char *    shell;
  58. {
  59.     int    number;
  60.  
  61. #ifdef unix
  62.     return system(string);
  63. #endif
  64. #ifdef ATARIST
  65.     return system(string);
  66. #endif
  67. #ifdef eon
  68.     return ((number = execl(shell, shell,"-c", string, 0)) == -1) ?
  69.         -1:    /* couldn't start the shell */
  70.         wait(number);    /* return its exit status */
  71. #endif
  72. #ifdef os9
  73.     int    status, pid;
  74.  
  75.     strcat(string, "\n");
  76.     if ((number = os9fork(shell, strlen(string), string, 0, 0, 0)) == -1)
  77.         return -1;        /* Couldn't start a shell */
  78.     do
  79.     {
  80.         if ((pid = wait(&status)) == -1)
  81.             return -1;    /* child already died!?!? */
  82.     } while (pid != number);
  83.  
  84.     return status;
  85. #endif
  86. }
  87.  
  88.  
  89. /*
  90.  *    Do commands to make a target
  91.  */
  92. void
  93. docmds1(np, lp)
  94. struct name *        np;
  95. struct line *        lp;
  96. {
  97.     bool            ssilent;
  98.     bool            signore;
  99.     int            estat;
  100.     register char *        q;
  101.     register char *        p;
  102.     char *            shell;
  103.     register struct cmd *    cp;
  104.  
  105.  
  106.     if (*(shell = getmacro("SHELL")) == '\0')
  107. #ifdef eon
  108.         shell = ":bin/esh";
  109. #endif
  110. #ifdef unix
  111.         shell = "/bin/sh";
  112. #endif
  113. #ifdef os9
  114.         shell = "shell";
  115. #endif
  116.  
  117.     for (cp = lp->l_cmd; cp; cp = cp->c_next)
  118.     {
  119.         strcpy(str1, cp->c_cmd);
  120.         expand(str1);
  121.         q = str1;
  122.         ssilent = silent;
  123.         signore = ignore;
  124.         while ((*q == '@') || (*q == '-'))
  125.         {
  126.             if (*q == '@')       /*  Specific silent  */
  127.                 ssilent = TRUE;
  128.             else           /*  Specific ignore  */
  129.                 signore = TRUE;
  130.             q++;           /*  Not part of the command  */
  131.         }
  132.  
  133.         if (!domake)
  134.             ssilent = 0;
  135.  
  136.         if (!ssilent)
  137.             fputs("    ", stdout);
  138.  
  139.         for (p=q; *p; p++)
  140.         {
  141.             if (*p == '\n' && p[1] != '\0')
  142.             {
  143.                 *p = ' ';
  144.                 if (!ssilent)
  145.                     fputs("\\\n", stdout);
  146.             }
  147.             else if (!ssilent)
  148.                 putchar(*p);
  149.         }
  150.         if (!ssilent)
  151.             putchar('\n');
  152.  
  153.         if (domake)
  154.         {            /*  Get the shell to execute it  */
  155.             if ((estat = dosh(q, shell)) != 0)
  156.             {
  157.                 if (estat == -1)
  158. #ifdef ATARIST
  159.                     fatal("Couldn't execute %s", q);
  160. #else
  161.                     fatal("Couldn't execute %s", shell);
  162. #endif
  163.                 else
  164.                 {
  165.                     printf("%s: Error code %d", myname, estat);
  166.                     if (signore)
  167.                         fputs(" (Ignored)\n", stdout);
  168.                     else
  169.                     {
  170.                         putchar('\n');
  171.                         if (!(np->n_flag & N_PREC))
  172.                             if (unlink(np->n_name) == 0)
  173.                                 printf("%s: '%s' removed.\n", myname,
  174.                                        np->n_name);
  175.                         exit(estat);
  176.                     }
  177.                 }
  178.             }
  179.         }
  180.     }
  181. }
  182.  
  183.  
  184. docmds(np)
  185. struct name *    np;
  186. {
  187.     register struct line *    lp;
  188.  
  189.  
  190.     for (lp = np->n_line; lp; lp = lp->l_next)
  191.         docmds1(np, lp);
  192. }
  193.  
  194.  
  195. #ifdef os9
  196. /*
  197.  *    Some stuffing around to get the modified time of a file
  198.  *    in an os9 file system
  199.  */
  200. getmdate(fd, tbp)
  201. struct sgtbuf *        tbp;
  202. {
  203.     struct registers    regs;
  204.     static struct fildes    fdbuf;
  205.  
  206.  
  207.     regs.rg_a = fd;
  208.     regs.rg_b = SS_FD;
  209.     regs.rg_x = &fdbuf;
  210.     regs.rg_y = sizeof (fdbuf);
  211.  
  212.     if (_os9(I_GETSTT, ®s) == -1)
  213.     {
  214.         errno = regs.rg_b & 0xff;
  215.         return -1;
  216.     }
  217.     if (tbp)
  218.     {
  219.         _strass(tbp, fdbuf.fd_date, sizeof (fdbuf.fd_date));
  220.         tbp->t_second = 0;    /* Files are only acurate to mins */
  221.     }
  222.     return 0;
  223. }
  224.  
  225.  
  226. /*
  227.  *    Kludge routine to return an aproximation of how many
  228.  *    seconds since 1980.  Dates will be in order, but will not
  229.  *    be lineer
  230.  */
  231. time_t
  232. cnvtime(tbp)
  233. struct sgtbuf        *tbp;
  234. {
  235.     long            acc;
  236.  
  237.  
  238.     acc = tbp->t_year - 80;        /* Baseyear is 1980 */
  239.     acc = acc * 12 + tbp->t_month;
  240.     acc = acc * 31 + tbp->t_day;
  241.     acc = acc * 24 + tbp->t_hour;
  242.     acc = acc * 60 + tbp->t_minute;
  243.     acc = acc * 60 + tbp->t_second;
  244.  
  245.     return acc;
  246. }
  247.  
  248.  
  249. /*
  250.  *    Get the current time in the internal format
  251.  */
  252. time(tp)
  253. time_t *        tp;
  254. {
  255.     struct sgtbuf        tbuf;
  256.  
  257.  
  258.     if (getime(&tbuf) < 0)
  259.         return -1;
  260.  
  261.     if (tp)
  262.         *tp = cnvtime(&tbuf);
  263.  
  264.     return 0;
  265. }
  266. #endif
  267.  
  268. #ifdef ATARIST
  269. /*
  270.  *    Get the current time in the internal format
  271.  */
  272. time(tp)
  273. time_t *        tp;
  274. {
  275.     if (tp)
  276.         *tp = Gettime();
  277.  
  278.     return 0;
  279. }
  280. #endif
  281.  
  282. /*
  283.  *    Get the modification time of a file.  If the first
  284.  *    doesn't exist, it's modtime is set to 0.
  285.  */
  286. void
  287. modtime(np)
  288. struct name *    np;
  289. {
  290. #ifdef unix
  291.     struct stat        info;
  292.     int            fd;
  293.  
  294.  
  295.     if (stat(np->n_name, &info) < 0)
  296.     {
  297.         if (errno != ENOENT)
  298.             fatal("Can't open %s; error %d", np->n_name, errno);
  299.  
  300.         np->n_time = 0L;
  301.     }
  302.     else
  303.         np->n_time = info.st_mtime;
  304. #endif
  305. #ifdef eon
  306.     struct stat        info;
  307.     int            fd;
  308.  
  309.  
  310.     if ((fd = open(np->n_name, 0)) < 0)
  311.     {
  312.         if (errno != ER_NOTF)
  313.             fatal("Can't open %s; error %02x", np->n_name, errno);
  314.  
  315.         np->n_time = 0L;
  316.     }
  317.     else if (getstat(fd, &info) < 0)
  318.         fatal("Can't getstat %s; error %02x", np->n_name, errno);
  319.     else
  320.         np->n_time = info.st_mod;
  321.  
  322.     close(fd);
  323. #endif
  324. #ifdef os9
  325.     struct sgtbuf    info;
  326.     int            fd;
  327.  
  328.  
  329.     if ((fd = open(np->n_name, 0)) < 0)
  330.     {
  331.         if (errno != E_PNNF)
  332.             fatal("Can't open %s; error %02x", np->n_name, errno);
  333.  
  334.         np->n_time = 0L;
  335.     }
  336.     else if (getmdate(fd, &info) < 0)
  337.         fatal("Can't getstat %s; error %02x", np->n_name, errno);
  338.     else
  339.         np->n_time = cnvtime(&info);
  340.  
  341.     close(fd);
  342. #endif
  343. #ifdef ATARIST
  344.     struct stat        info;
  345.     extern int        getstat();        /*  in ststuff.c  */
  346.     extern void        FlipWords();        /*  in ststuff.c  */
  347.  
  348.     if (getstat(np->n_name, &info) < 0)
  349.         np->n_time = 0L;
  350.     else
  351.     {
  352.         FlipWords(&info.st_mod);
  353.         np->n_time = info.st_mod;
  354.     }
  355. #endif
  356. }
  357.  
  358.  
  359. /*
  360.  *    Update the mod time of a file to now.
  361.  */
  362. void
  363. touch(np)
  364. struct name *    np;
  365. {
  366.     char    c;
  367.     int        fd;
  368.  
  369.  
  370.     if (!domake || !silent)
  371.         printf("    touch(%s)\n", np->n_name);
  372.  
  373.     if (domake)
  374.     {
  375. #ifdef unix
  376.         long    a[2];
  377.  
  378.         a[0] = a[1] = time(0);
  379.         if (utime(np->n_name, &a[0]) < 0)
  380.             printf("%s: '%s' not touched - non-existant\n",
  381.                     myname, np->n_name);
  382. #endif
  383. #ifdef eon
  384.         if ((fd = open(np->n_name, 0)) < 0)
  385.             printf("%s: '%s' not touched - non-existant\n",
  386.                     myname, np->n_name);
  387.         else
  388.         {
  389.             uread(fd, &c, 1, 0);
  390.             uwrite(fd, &c, 1);
  391.         }
  392.         clo